package com.example.security.controller;

import com.example.security.config.JwtProperties;
import com.example.security.exception.InvalidTokenException;
import com.example.security.service.JwtService;
import com.example.security.service.SsoService;
import com.example.security.service.UserService;
import com.example.security.vo.LoginRequest;
import com.example.security.vo.LoginResponse;
import com.example.security.vo.TokenResponse;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.web.bind.annotation.*;

import java.util.concurrent.TimeUnit;

/**
 * SSO控制器
 */
@Slf4j
@Tag(name = "SSO接口")
@RestController
@RequestMapping("/api/sso")
@RequiredArgsConstructor
public class SsoController {
    @Autowired
    private  SsoService ssoService;
    @Autowired
    private  JwtService jwtService;
    @Autowired
    private  UserService userService;
    @Autowired
    private  RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private  JwtProperties jwtProperties;
    @Autowired
    private UserDetailsService userDetailsService ;
    
    @PostMapping("/login")
    @Operation(summary = "SSO登录")
    public ResponseEntity<LoginResponse> login(@RequestBody @Valid LoginRequest request) {
        return ResponseEntity.ok(ssoService.login(request));
    }
    
    @GetMapping("/validate")
    @Operation(summary = "验证SSO票据")
    public ResponseEntity<String> validateTicket(
            @RequestParam String ticket,
            @RequestParam String clientId
    ) {
        return ResponseEntity.ok(ssoService.validateTicket(ticket, clientId));
    }
    
    @PostMapping("/refresh")
    @Operation(summary = "刷新token")
    public ResponseEntity<TokenResponse> refreshToken(@RequestHeader("Authorization") String authorization) {
        try {
            String oldToken = authorization.substring(7); // 去掉"Bearer "前缀
            String username = jwtService.extractUsername(oldToken);
            
            // 验证旧token是否在刷新期内
            String refreshKey = "refresh:" + username;
            String storedToken = (String) redisTemplate.opsForValue().get(refreshKey);
            
            if (!oldToken.equals(storedToken)) {
                throw new InvalidTokenException("Token已失效，请重新登录");
            }
            
            // 获取用户信息并生成新token
            UserDetails userDetails = userDetailsService.loadUserByUsername(username);
            String newToken = jwtService.generateToken(userDetails);
            
            // 保存新token到Redis
            redisTemplate.opsForValue().set(
                "token:" + username,
                newToken,
                jwtProperties.getExpireTime(),
                TimeUnit.SECONDS
            );
            
            return ResponseEntity.ok(new TokenResponse(newToken));
        } catch (Exception e) {
            log.error("刷新token失败", e);
            throw new InvalidTokenException("刷新token失败");
        }
    }

    @PostMapping("/logout")
    @Operation(summary = "SSO注销")
    public ResponseEntity<Void> logout(@RequestHeader("Authorization") String authorization) {
        String token = authorization.substring(7);
        ssoService.logout(token);
        return ResponseEntity.ok().build();
    }
} 